package com.sf.gis.boot.rcboot.config;

import cn.hutool.core.util.StrUtil;
import com.github.benmanes.caffeine.cache.*;
import com.sf.gis.boot.rcboot.entity.CommunityStatist;
import com.sf.gis.boot.rcboot.service.ICommunityStatistService;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;

/**
 * @author 80004819
 * @ClassName:
 * @Description:
 * @date 2020年09月21日 15:50:52
 */
@Configuration
@Slf4j
public class CaffeineConfig {


    @Autowired
    private ICommunityStatistService iCommunityStatistService;


    /**
     * 手动加载缓存
     * @return
     */
    @Bean("cache")
    public Cache<String, Object> cache() {
        Cache<String, Object> cache = Caffeine.newBuilder().initialCapacity(500)
                .maximumSize(100000)
                //弱引用key，value,不管当前内存空间足够与否，都会回收它的内存
//                .weakKeys()
//                .weakValues()
                //软引用，内存不足就会回收
                .softValues()
                .expireAfterWrite(20, TimeUnit.SECONDS)
                .expireAfterAccess(20, TimeUnit.SECONDS)
                //手动加载cache不支持写入后自动刷新
                //  .refreshAfterWrite(30, TimeUnit.SECONDS)
                .removalListener((key, value, cause) -> log.info("移除的key：{}，移除的value：{}，移除原因：{}", key, value, cause))
                .recordStats()
                .build();
        return cache;
    }

    /**
     * 自动加载缓存
     * @return
     */
    @Bean("loadingCache")
    public LoadingCache<String, Object> loadingCache() {
        LoadingCache<String, Object> cache = Caffeine.newBuilder().initialCapacity(500)
                .maximumSize(100000)
//                .weakKeys()
//                .weakValues()
                .softValues()
                .expireAfterWrite(500, TimeUnit.SECONDS)
                .expireAfterAccess(500, TimeUnit.SECONDS)
                .refreshAfterWrite(300, TimeUnit.SECONDS)
                .removalListener(
                        (key, value, cause) ->
                                log.info("移除咯key：{}，移除的value：{}，移除原因：{}", key, value, cause)
                )
                .recordStats()
                .build(key -> createValue(key));
        return cache;
    }

    private Object createValue(String key) {
        return null;
    }

    /**
     * 异步加载缓存
     * @return
     */
    @Bean("asyncLoadingCache")
    public AsyncLoadingCache<String, Object> asyncLoadingCache() {
        AsyncLoadingCache<String, Object> AsyncLoadingCache = Caffeine.newBuilder().initialCapacity(500)
                .maximumSize(100000)
                //异步加载cache不支持弱引用和软引用
                //.weakKeys()
                //.weakValues()
                .expireAfterWrite(20, TimeUnit.SECONDS)
                .expireAfterAccess(20, TimeUnit.SECONDS)
                .refreshAfterWrite(10, TimeUnit.SECONDS)
                .removalListener((key, value, cause) -> log.info("移除的key：{}，移除的value：{}，移除原因：{}", key, value, cause))
                .recordStats()
                .buildAsync(key -> createValue(key));
        return AsyncLoadingCache;
    }

}
